package app.keter.portal.security.core;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.*;

/**
 * 当前应用的用户认证信息：
 * 应用程序结合项目实际情况进行适配改造即可
 */
public class UserDetailsImpl implements UserDetails {
    private static final Logger logger = LoggerFactory.getLogger(UserDetailsImpl.class);
    private final String id;
    private final String username;
    private String password;
    private String email;
    /**
     * 由于authorities的数据类型（Collection）比较特殊
     * 因此JSON工具库转换时（如Jackson、JsonKit、JSONObject等）会将
     * "[ROLE_ADMIN, ROLE_USER]"
     * 自动转换成
     * "authorities":[{"authority":"ROLE_ADMIN"},{"authority":"ROLE_USER"}]
     * 导致使用时不满足SpringSecurity框架的RBAC认证逻辑
     */
    private  Collection<? extends GrantedAuthority> authorities;

    public UserDetailsImpl(
            String id,
            String username,
            String password,
            String email,
            JSONArray roles) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.email = email;
        this.authorities = getAuthoritiesFromRoles(roles);
    }

    public String getId() {
        return id;
    }

    public String getEmail() {
        return email;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    /**
     * 从[{"authority":"ROLE_ADMIN"},{"authority":"ROLE_USER"}]中提取ROLE_ADMIN和ROLE_USER放入authorities
     *
     * @param roles
     * @return
     */
    public static Collection<? extends GrantedAuthority> getAuthoritiesFromRoles(JSONArray roles){
        Collection<SimpleGrantedAuthority> authorities = new ArrayList<>(roles.size());
        for (int i = 0; i < roles.size(); i++) {
            String roleString = roles.getString(i);
//            logger.info("role object:{}", roleString);
            // 处理JSON自动转换时添加了内容的问题:只保留"authority"的属性值
            if(roleString.contains("authority:")){
                authorities.add(new SimpleGrantedAuthority(JSONObject.parseObject(roleString).getString("authority")));
            }
            else{
                authorities.add(new SimpleGrantedAuthority(roles.getString(i)));
            }
        }
        return authorities;
    }

    @Override
    public String toString(){
        return JSON.toJSONString(this);
    }
}
